﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Text;

namespace Common
{
    /// <summary>
    /// 
    /// </summary>
    public static class HttpTool
    {
        private const int DefaultConnectionLimit = 20;

        /// <summary>
        /// Http方式请求获取Http响应
        /// </summary>
        /// <param name="url">请求的Url地址</param>
        /// <param name="encoding">参数的编码方式</param>
        /// <param name="method">Http请求方式</param>
        /// <param name="paramList">请求的参数列表</param>
        /// <param name="proxy">代理</param>
        /// <param name="timeOut">超时时间</param>
        /// <returns>Http响应</returns>
        public static HttpWebResponse GetResponse(string url, Encoding encoding, string method = HttpMethods.Post, Dictionary<string, object> paramList = null, IWebProxy proxy = null, int timeOut = 100*1000)
        {
            ServicePointManager.DefaultConnectionLimit = DefaultConnectionLimit;
            HttpWebRequest request = null;
            HttpWebResponse response = null;
            StreamWriter writer = null;
            try
            {
                string paramData = JoinParameters(paramList);

                switch (method)
                {
                    case HttpMethods.Post:
                        request = (HttpWebRequest)WebRequest.Create(url);
                        request.ContentLength = Encoding.UTF8.GetByteCount(paramData);
                        writer = new StreamWriter(request.GetRequestStream(), encoding);
                        writer.Write(paramData);
                        writer.Flush();
                        break;
                    case HttpMethods.Get:
                        request = (HttpWebRequest)WebRequest.Create(paramData == null ? url : url + "?" + paramData);
                        break;
                    default:
                        return null;
                }
                request.Method = method;
                request.ContentType = "application/x-www-form-urlencoded";
                request.CookieContainer = new CookieContainer();
                request.Timeout = timeOut;
                request.Proxy = proxy;
                response = (HttpWebResponse)request.GetResponse();
                return response;
            }
            catch (Exception)
            {
                if (request != null) request.Abort();
                if (response != null) response.Close();
                if (writer != null) writer.Close();
                return null;
            }
            finally
            {
                if (writer != null)
                {
                    writer.Flush();
                    writer.Close();
                }
            }
        }

        private static string JoinParameters(Dictionary<string, object> paramList)
        {
            if (paramList == null || paramList.Count == 0) return null;
            StringBuilder paramBuilder = new StringBuilder();
            foreach (string key in paramList.Keys)
            {
                string escapeKey = Uri.EscapeDataString(key);
                if (paramList[key] is string[])
                {
                    string[] arrayParam = paramList[key] as string[];
                    if (arrayParam != null)
                    {
                        foreach (string item in arrayParam)
                        {
                            paramBuilder.Append(escapeKey + "=" + item + "&");
                        }
                        break;
                    }
                }
                string escapeValue = paramList[key] == null || String.IsNullOrEmpty(paramList[key].ToString())
                                         ? String.Empty
                                         : Uri.EscapeDataString(paramList[key].ToString());
                paramBuilder.Append(escapeKey + "=" + escapeValue + "&");
            }
            return paramBuilder.ToString().Substring(0, paramBuilder.Length - 1);
        }
    }
}
